#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/kthread.h>
#include <linux/delay.h>

MODULE_LICENSE("GPL");

static int __init test_init(void);
static void __exit test_exit(void);

/******* Global var **********/

struct task_struct *old;
static wait_queue_head_t head;


// 子进程

int my_function(void*argc)
{
	printk("[%s] pid = [%d] \n", __func__, current->pid);
	printk("[%s] init 进程状态 old->state: [%ld] \n", __func__, old->state);

	__wake_up(&head, TASK_ALL,0, NULL);                   //调用函数唤醒等待队列中的进程
	
	//显示函数__wake_up( )调用之后的init进程的状态
	
	printk("[%s]state of the init function after __wake_up is :[%ld] \n", __func__, old->state);
	printk("out the kernel thread function\n");
	return 0;
}

int __init test_init(void)
{
	char namefrm[] = "__wake_up";
	long time_out;

	struct task_struct *result;
	wait_queue_t data;

	printk("---------------------\n [%s] eneter! \n",__func__);

	result = kthread_create_on_node(my_function, NULL, -1, namefrm );
	
	printk("the pid of the new thread is:%d\n", result->pid); //显示新线程的PID值
	
	printk("the current pid is:%d\n", current->pid);           //显示当前进程的PID值
	
	init_waitqueue_head(&head);               //初始化等待队列头元素
	
	init_waitqueue_entry(&data, current);     //用当前进程初始化等待队列中的一个元素
	
	add_wait_queue(&head, &data);             //将等待队列元素加入等待队列中
	
	old = current;                       //记录当前进程的信息
	
	printk("[%s]state of the init function after __wake_up is :[%ld] \n", __func__, old->state);
	
	wake_up_process(result);                  //唤醒新创建的线程
	
	time_out=schedule_timeout_uninterruptible(1000*10);     //让当前进程进入睡眠状态

	printk("the schedule timeout is:%ld\n", time_out);       //显示函数返回结果
	
	printk("---------------------\n [%s] init out \n",__func__);
	return 0;
}


void __exit test_exit(void)
{
	printk("[%s] exit! \n",__func__);
}

module_init(test_init);
module_exit(test_exit);

